#pragma once
#include <string>
#include <cctype>
#include <cassert>
#include <cstring>
#include <utility>
#include <jsoncpp/json/json.h>
#define CRLF "\r\n"
#define CRLF_LEN (strlen(CRLF))
#define SPACE " "
#define SPACE_LEN (strlen(" "))

using namespace std;

// 添加报头 如果有错误就返回false
// 100 + 200 -> len\r\n100 + 200\r\n
void encode(string &str)
{
    int len = str.size();
    str = to_string(len) + string(CRLF) + str + string(CRLF);
}
// 检验报头完整并且去掉报头
// len\r\n100 + 200\r\n -> 100 + 200
pair<bool, string> decode(string &str)
{
    // 第一个分隔符
    size_t pos = str.find(CRLF);
    if (pos == string::npos)
    {
        return {false, string()};
    }
    // 获取有效载荷长度
    string len_str = str.substr(0, pos);
    int len_expect = stoi(len_str);
    // 验证长度
    int len_actual = str.size() - 2 * CRLF_LEN - pos;
    if (len_actual - len_expect)
    {
        return {false, string()};
    }
    string ret_str = str.substr(pos + CRLF_LEN, len_actual);
    // 从str中去除报文
    str.erase(0, len_str.size() + 2 * CRLF_LEN + ret_str.size());
    return {true, ret_str};
}
struct response
{
    // 序列化 struct -> string
    string serialize()
    {
#ifdef DIY
        // 自己序列化
        return to_string(_exit_code) + SPACE + to_string(_result);
#else
        // json
        Json::Value root;
        root["exit_code"] = _exit_code;
        root["result"] = _result;
        // Json::StyledWriter sw;
        Json::FastWriter fw;
        return fw.write(root);
#endif
    }
    // 反序列化 string -> struct
    void deserialize(const string &str)
    {
#ifdef DIY
        int pos = str.find(SPACE);
        _exit_code = stoi(str.substr(0, pos));
        _result = stoi(str.substr(pos + 1));
#else
        // json
        Json::Value root;
        Json::Reader reader;
        reader.parse(str, root);
        _exit_code = root["exit_code"].asInt();
        _result = root["result"].asInt();
#endif
    }
    int _exit_code;
    int _result;
};
struct request
{
    // 序列化 struct -> string
    // a + b
    string serialize()
    {
#ifdef DIY
        return to_string(_a) + SPACE + _op + SPACE + to_string(_b);
#else
        // json
        Json::Value root;
        root["a"] = _a;
        root["op"] = _op;
        root["b"] = _b;
        Json::FastWriter fw;
        return fw.write(root);
#endif
    }
    // 反序列化 string -> struct
    // a + b
    void deserialize(const string &str)
    {
#ifdef DIY
        int space_pos = str.find(SPACE);
        _a = stoi(str.substr(0, space_pos));
        _op = str[space_pos + SPACE_LEN];
        _b = stoi(str.substr(space_pos + 2 * SPACE_LEN + 1));
#else
        // json
        Json::Reader reader;
        Json::Value root;
        reader.parse(str, root);
        _a = root["a"].asInt();
        _b = root["b"].asInt();
        // 字符 用asInt 一样
        _op = root["op"].asInt();
#endif
    }
    int _a;
    int _b;
    char _op;
};
// 1+1或者 1+   -1或者1        ++1
pair<bool, request> make_request(string &str)
{
    int pos = -1;
    // 遍历
    for (int i = 1; i < str.size(); i++)
    {
        if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' || str[i] == '%')
        {
            if (i + 1 < str.size() && !(str[i + 1] == '+' || str[i + 1] == '-'))
            {
                pos = i;
                break;
            }
        }
    }
    request req;
    if (pos == -1)
    {
        return {false, req};
    }
    req._a = stoi(str.substr(0, pos));
    req._op = str[pos];
    req._b = stoi(str.substr(pos + 1));
    return {true, req};
}
